#include<stdio.h>
#include<stdlib.h>
#include<unistd.h>
#include<string.h>
#include<malloc.h>

#include "font.h"

#define CHN_FONT_PATH "/mnt/font/Font32.DZK"
#define ASC_FONT_PATH "/mnt/font/MicrosoftJHenghei128.DZK"


static char getBitFromData(char *dataStream, int i, int j, int _srcHeight);
static void output_by_terminal(CharOBJ *OBJ);

int switchChineseChar2Mat(CharOBJ *OBJ)
{ 
    unsigned char qh;
    unsigned char ql;
    unsigned long foffset;
    int srcSize, tarSize;
    const int tarHeight = OBJ->height;
    const int tarWidth = OBJ->height;
    int ret = 0;
    int i, j;

    if(OBJ->charType != CharType_Chinese)
    {
        printf("char type invalid!\n");
        return -1;
    }

    FILE *fp = fopen(CHN_FONT_PATH, "rb");
    if(fp == NULL)
    {
        printf("Open %s fail\n", CHN_FONT_PATH);
        return -1;
    }

    tarSize = tarHeight*tarWidth;
    srcSize=(srcHeight/8+((srcHeight%8)?1:0))*(srcHeight);

    qh=OBJ->charPtr[0];
	ql=OBJ->charPtr[1];
    if(qh<0xa1||ql<0xa1||ql==0xff||qh==0xff)
	{   	
        printf("invalid Chinese char! %d %d\n", ql, qh);  
	    return -1;  
	}    
	ql-=0xa1;  
	qh-=0xa1;  

	foffset=((unsigned long)94*qh+ql)*srcSize;	

    ret = fseek(fp, foffset, SEEK_SET);
    if(ret < 0)
    {
        printf("seek file fail %d\n", ret);
        return ret;
    }

    /* 读取原数据 */
    char srcData[srcSize];
    ret = fread(srcData, 1, srcSize, fp);
    if(ret <= 0)
    {
        printf("read file fail %d\n", ret);
        return ret;
    }
    // printf("read %d success!\n", ret);

    ret = fclose(fp);
    if(ret != 0)
    {
        printf("close file fail![%d]\n", ret);
        return -1;
    }

    /*申请一维数组的指针的内存*/
    char **matMem = malloc(sizeof(char*)*tarWidth);
    if(matMem == NULL) 
    {
        printf("Can't malloc DMA memory!\n");
        fclose(fp);
        return -1;
    }

    for(i=0;i<tarWidth;i++)
    {
        /*给每个一维数组申请内存*/
        matMem[i] = malloc(tarHeight);
        if(matMem[i] == NULL)
        {
            printf("Can't malloc DMA memory!\n");
            return -1;
        }
        for(j=0;j<tarHeight;j++)
        {
            /*转换成目标长宽比*/
            matMem[i][j] = getBitFromData(srcData, i*srcHeight/tarWidth, j*srcHeight/tarHeight, srcHeight);
        }
    }
    OBJ->matBuff = matMem;

    //output_by_terminal(OBJ);
}


int switchAsciiChar2Mat(CharOBJ *_OBJ)
{
    char thisChar = *(_OBJ->charPtr);
    int tarHeight = _OBJ->height;
    int tarWidth  = _OBJ->height/2;
    int ret;
    int i, j;

    /* 判断字符类型 */
    if(_OBJ->charType != CharType_Ascii)
    {
        printf("char type invalid!\n");
        return -1;
    }
    if(*(_OBJ->charPtr) >= 0x80)
    {
        printf("not a ascii char!\n");
        return -1;
    }

    FILE *fp = fopen(ASC_FONT_PATH, "rb");
    if(fp == NULL)
    {
        printf("Open %s fail\n", ASC_FONT_PATH);
        return -1;
    }

    int srcSize = (AsciiSrcHeight/8+((AsciiSrcHeight%8)?1:0))*(AsciiSrcHeight);
    int foffset = thisChar*srcSize;
    ret = fseek(fp, foffset, SEEK_SET);
    if(ret < 0)
    {
        printf("seek file fail %d\n", ret);
        return ret;
    }

    char srcData[srcSize];
    ret = fread(srcData, 1, srcSize, fp);
    if(ret <= 0)
    {
        printf("read file fail %d\n", ret);
        return ret;
    }
    // printf("read %d success!\n", ret);

    ret = fclose(fp);
    if(ret != 0)
    {
        printf("close file fail![%d]\n", ret);
        return -1;
    }

    /*申请一维数组的指针的内存*/
    char **matMem = malloc(sizeof(char*)*tarWidth);
    if(matMem == NULL) 
    {
        printf("Can't malloc DMA memory!\n");
        return -1;
    }
    for(i=0;i<tarWidth;i++)
    {
        /*给每个一维数组申请内存*/
        matMem[i] = malloc(tarHeight);
        if(matMem[i] == NULL)
        {
            printf("Can't malloc DMA memory!\n");
            return -1;
        }
        for(j=0;j<tarHeight;j++)
        {
             matMem[i][j] = getBitFromData(srcData, i*AsciiSrcHeight/2/tarWidth, j*AsciiSrcHeight/tarHeight, AsciiSrcHeight);
        }
    }
    _OBJ->matBuff = matMem;

    // output_by_terminal(_OBJ);
}

/**
 * @brief 从连续的数据中获取字模第i列，第j行的位
 * 
 * @param _OBJ 
 * @param i 
 * @param j 
 */
char getBitFromData(char *dataStream, int i, int j, int _srcHeight)
{
    int row_len = (_srcHeight/8+((_srcHeight%8)?1:0));    //一行多少字节
    int col_num = i/8;
    int bit_num = i%8;

    return (dataStream[row_len*j+col_num]&(0x80>>bit_num))?1:0;
}

void output_by_terminal(CharOBJ *OBJ)
{
    int i, j;
    int height, width;
    height = OBJ->height;
    if(OBJ->charType == CharType_Ascii)
        width = height/2;
    else
        width = height;
    for(i=0;i<height;i++)
    {
        for(j=0;j<width;j++)
        {
            if(OBJ->matBuff[j][i] != 0)
                printf("#");
            else
                printf(" ");
        }
        printf("\n");
    }
}

void freeStringMem(StringOBJ *_obj)
{
    int i;
    int _width = _obj->width;
    for(i=0;i<_width;i++)
    {
        free(_obj->matBuff[i]);
    }
}

